﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Derbster.Domain;

namespace Derbster.Mock
{
    /// <summary>
    /// This is an in-memory version of repository. Note, we don't use the singleton pattern here. 
    /// Instead, we count on Unity to control the lifecycle of these objects. By default, we use
    /// a container-controlled lifecycle, so only one instance of a repository is returned per container.
    /// </summary>
    public class MockMatchRepository : IMatchRepository
       
    {
        private readonly ObservableCollection<Match> _all;

        public MockMatchRepository()
        {
            _all = new ObservableCollection<Match>();
        }

        public Match Create(bool isRegulation, bool isSanctioned, Roster firstTeamRoster, Roster secondTeamRoster, string name)
        {
            
            Match newMatch = new Match(isRegulation, isSanctioned, firstTeamRoster, secondTeamRoster, name);
            newMatch.MatchId = _all.Count + 1;
            _all.Add(newMatch);

            return newMatch;
        }

        public Match Create(
            bool isRegulation,
            bool isSanctioned,
            Roster firstTeamRoster,
            Roster secondTeamRoster,
            string name,
            string location)
        {
            Match newMatch = new Match(isRegulation, isSanctioned, firstTeamRoster, secondTeamRoster, name, location);
            newMatch.MatchId = _all.Count + 1;
            _all.Add(newMatch);

            return newMatch;
        }

        public Match Create(
            bool isRegulation,
            bool isSanctioned,
            Roster firstTeamRoster,
            Roster secondTeamRoster,
            string name,
            string location,
            DateTime? when)
        {
            Match newMatch = new Match(isRegulation, isSanctioned, firstTeamRoster, secondTeamRoster, name, location, when);
            newMatch.MatchId = _all.Count + 1;
            _all.Add(newMatch);

            return newMatch;
        }

        public Match FindById(int id)
        {
            return _all.SingleOrDefault(m => m.MatchId == id);
        }

        public Match FindByGlobalIdentifier(Guid globalGuid)
        {
            return _all.SingleOrDefault(m => m.GlobalIdentifier == globalGuid);
        }

        public Match FindByName(string name)
        {
            return _all.SingleOrDefault(m => m.Name.ToLower() == name.ToLower());
        }

        public IEnumerable<Match> FindByDate(DateTime fromDate, DateTime toDate)
        {
            return _all.Where(m => m.When.HasValue && m.When.Value >= fromDate && m.When.Value <= toDate).AsEnumerable();
        }

        public IEnumerable<Match> FindByLocation(string location)
        {
            return _all.Where(m => !String.IsNullOrWhiteSpace(m.Location) && m.Location.ToLower() == location.ToLower()).AsEnumerable();
        }

        public Match Update(Match match)
        {
            return match;
        }

        public void Delete(Match match)
        {
            _all.Remove(match);
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            return;
        }

        public IEnumerator<Match> GetEnumerator()
        {
            return _all.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public Expression Expression
        {
            get
            {
                return _all.AsQueryable().Expression;
            }
        }

        public Type ElementType
        {
            get
            {
                return _all.AsQueryable().ElementType;
            }
        }

        public IQueryProvider Provider
        {
            get
            {
                return _all.AsQueryable().Provider;
            }
        }
    }
}
